<template>
  <div id="app">
    <!-- 自定义标题栏 -->
    <div class="custom-titlebar">
      <div class="title-content">
        <div class="title-icon">
          <div class="fire-icon">🔥</div>
        </div>
        <div class="title-text">
          <div class="main-title">火炬之光掉落统计插件</div>
          <div class="sub-title">By: 王天紫</div>
        </div>
      </div>
      <div class="titlebar-buttons">
        <button class="titlebar-btn minimize-btn" @click="minimizeWindow" title="最小化">
          <svg width="12" height="12" viewBox="0 0 12 12">
            <rect x="0" y="5" width="12" height="2" fill="currentColor" />
          </svg>
        </button>
        <button class="titlebar-btn close-btn" @click="closeWindow" title="关闭">
          <svg width="12" height="12" viewBox="0 0 12 12">
            <path d="M1,1 L11,11 M11,1 L1,11" stroke="currentColor" stroke-width="2" fill="none" />
          </svg>
        </button>
      </div>
    </div>
    <div v-if="!isSimpleMode">
      <!-- 检测状态提示 -->
      <div v-if="isDetecting" class="detection-status">
        <div class="spinner"></div>
        <p>正在自动检测游戏进程...</p>
        <p class="timeout-tip" v-if="showTimeoutTip">检测时间较长，请确保游戏已启动</p>
      </div>

      <!-- 检测失败提示 -->
      <div v-if="detectFailed" class="detection-error-container">
        <div class="detection-error-card">
          <div class="error-icon-wrapper">
            <div class="error-icon">
              <i class="el-icon-warning"></i>
            </div>
          </div>

          <div class="error-content">
            <h3 class="error-title">未检测到游戏进程</h3>

            <div class="path-info-section">
              <div class="path-header">
                <i class="el-icon-folder-opened"></i>
                <span>日志文件路径</span>
              </div>
              <div class="path-content">
                <code>TapTap\PC Games\TorchlightInfinite\UE_game\TorchLight\Saved\Logs\UE_game.log</code>
              </div>
              <p class="path-tip">如果自动检测失败，您可以手动选择日志文件位置</p>
            </div>
          </div>

          <div class="action-buttons">
            <el-button @click="retryDetection" type="primary" icon="el-icon-refresh" class="retry-btn">
              重新检测
            </el-button>
            <el-button @click="manualSelectLog" icon="el-icon-folder-opened" class="manual-btn">
              选择日志
            </el-button>
          </div>
        </div>
      </div>

      <!-- 主界面 -->
      <div v-if="!isDetecting && !detectFailed" class="main-content">
        <!-- 顶部固定区域 -->
        <div class="top-section">
          <TimeStats :current-minutes="currentMinutes" :current-seconds="currentSeconds" :current-rate="currentRate"
            :current-profit="currentProfit" :total-minutes="totalMinutes" :total-seconds="totalSeconds"
            :total-rate="totalRate" :total-profit="totalProfit" />

          <div class="divider"></div>

          <!-- 回本状态显示 -->
          <div class="break-even-section">
            <div class="divider-line"></div>
            <div class="break-even-text">
              已掉落 {{ totalDropsValue.toFixed(0) }} <img :src="require('@/../public/assets/huo.png')" alt="火"
                class="rate-icon">(包含对应价值物品)
            </div>
            <div class="divider-line"></div>
          </div>
        </div>

        <!-- 中间滚动区域 -->
        <div class="scroll-section">
          <ItemsPanel :filtered-items="filteredItems" :is-running="isRunning" :price-data="priceData" />
        </div>

        <!-- 底部固定区域 -->
        <div class="bottom-section">
          <ActionButtons @show-author="showAuthor" @show-filter="showFilter" @show-log="showLog"
            @show-settings="showSettings" @show-instructions="showInstructions" @clear-items="clearItemsPanel"
            @show-total-drops="showTotalDrops" @toggle-simple-mode="toggleSimpleMode" :is-running="isRunning"
            :buttons-enabled="buttonsEnabled" :is-simple-mode="isSimpleMode" />
        </div>

        <!-- 弹窗区域 -->
        <el-dialog title="总掉落记录" :visible.sync="totalDropsVisible" width="600px" @close="totalDropsVisible = false"
          :modal="false" :append-to-body="true" :show-close="true" custom-class="total-drops-dialog">
          <div style="padding: 15px;" class="dialog-content">
            <el-table :data="allDropsList" border class="total-drops-table">
              <el-table-column prop="name" label="物品名称" width="200"></el-table-column>
              <el-table-column prop="count" label="数量" width="100"></el-table-column>
              <el-table-column prop="price" label="单价" width="100"></el-table-column>
              <el-table-column prop="totalValue" label="总价值" width="100"
                :formatter="(row) => row.totalValue.toFixed(0)"></el-table-column>
            </el-table>
          </div>
        </el-dialog>

        <AuthorDialog :visible.sync="authorDialogVisible" />

        <FilterDialog :visible.sync="filterDialogVisible" :item-list="itemList" :filtered-ids="filteredItemsIds"
          @update-filter="updateFilter" />

        <SettingsDialog :visible.sync="settingsDialogVisible" :cost-per-map="costPerMap" :count-income="countIncome"
          :opacity="opacity" @update-cost="handleCostUpdate" @update-count="handleCountUpdate"
          @update-opacity="handleOpacityUpdate" />
      </div>

      <!-- 免责声明全屏覆盖层 -->
      <div v-if="disclaimerVisible" class="disclaimer-overlay">
        <div class="disclaimer-container">
          <div class="disclaimer-header">
            <h2>免责声明</h2>
          </div>

          <div class="disclaimer-content">
            <div class="disclaimer-text">
              <h3>重要提示：请仔细阅读</h3>
              <p>本软件《火炬之光掉落统计插件》是一款为《火炬之光：无限》游戏开发的辅助工具，主要用于记录和分析游戏内的物品掉落情况。</p>

              <h4>使用须知：</h4>
              <ul>
                <li>✅ 本软件仅通过读取游戏日志文件来获取信息，不修改游戏内存、不注入代码</li>
                <li>✅ 本软件不提供任何游戏自动化功能，不影响游戏平衡</li>
                <li>✅ 本软件完全免费，仅供个人学习交流使用</li>
              </ul>

              <h4>风险提示：</h4>
              <ul>
                <li>⚠️ 使用任何第三方软件都存在账号安全风险</li>
                <li>⚠️ 游戏开发商有权对使用第三方软件的行为进行处罚</li>
                <li>⚠️ 如因使用本软件导致账号被封禁，开发者不承担任何责任</li>
              </ul>

              <h4>用户承诺：</h4>
              <p>我已知晓并理解上述风险，自愿使用本软件，并承诺：</p>
              <ul>
                <li>• 仅将本软件用于个人游戏数据分析</li>
                <li>• 不利用本软件进行任何破坏游戏平衡的行为</li>
                <li>• 自行承担使用本软件可能带来的一切风险</li>
              </ul>

              <div class="countdown-section">
                <p class="countdown-text">本声明只会在第一次使用时出现，请务必仔细阅读。</p>
                <p class="countdown-text">同意则视为已充分理解以上声明</p>
              </div>
            </div>
          </div>

          <div class="disclaimer-footer">
            <el-button type="primary" :disabled="countdown > 0" @click="acceptDisclaimer" class="accept-btn"
              size="large">
              {{ countdown > 0 ? `同意并继续 (${countdown}s)` : '同意并继续' }}
            </el-button>
          </div>
        </div>
      </div>

      <!-- 开发者提示弹窗 -->
      <el-dialog title="开发者的话" :visible.sync="developerTipsVisible" :width="dialogWidth" top="11vh" :modal="false"
        :append-to-body="true" :show-close="false" custom-class="developer-tips-dialog"
        style="height: 60%; max-height: 80vh;">

        <div class="developer-tips-content">
          <!-- 标题区域 -->
          <div class="tips-header">
            <div class="tips-icon">💡</div>
            <h3>欢迎使用火炬之光掉落统计插件</h3>
          </div>

          <!-- 内容区域 -->
          <div class="tips-sections">
            <!-- 开发者的话 -->
            <div class="tips-section">
              <h4>1. 软件声明</h4>
              <p>本软件使用的技术栈为：Electron + Vue.js + Element UI + Node.js，已在gitee开源。</p>
              <p>目前为测试版本，如果你在使用过程中遇到任何问题，请通过软件内作者按钮与我联系。</p>
              <p>后续更新迭代操作均在群内完成，如需获取最新版本请加群自行获取。</p>
              <p>开发者后续还会开发一些围绕游戏《火炬之光:无限》而创作的其他插件，如想测试请关注开发者。</p>
            </div>

            <!-- 使用方法 -->
            <div class="tips-section">
              <h4>2. 使用方法</h4>
              <p>开启游戏后启动本软件，然后在游戏内点击设置-其他设置-开启日志-返回登录-重新进入游戏。</p>
            </div>

            <!-- 注意事项 -->
            <div class="tips-section warning-section">
              <h4>3. 注意事项</h4>
              <p>最好将所有物品准备齐全再进行刷图，例如购买足够的回响，罗盘等物品。本软件在进入游戏时读取了背包日志，所以后续有操作背包物品的操作(例如交易行购买或出售物品)会导致物品数量出错，最终会导致统计数据偏差过大。
              </p>
              <p>如果你在本软件开启时操作了背包物品，重复一遍使用方法即可(点击设置-其他设置-开启日志-返回登录-重新进入游戏)此时会重新读取背包日志。</p>
              <p>此BUG会在空闲时进行修复，获取最新版请进群获取</p>
            </div>
          </div>
        </div>

        <!-- 底部按钮 -->
        <div slot="footer" class="tips-footer">
          <el-button type="primary" size="medium" @click="developerTipsVisible = false" class="confirm-btn">
            我知道了
          </el-button>
        </div>
      </el-dialog>

      <!-- 说明弹窗 -->
      <el-dialog title="使用须知" :visible.sync="instructionsVisible" width="520px" :modal="false" :append-to-body="true"
        custom-class="instructions-dialog" @close="handleInstructionsClose">
        <div class="instructions-content">
          <!-- 重要提示 -->
          <div class="important-notice">
            <div class="notice-icon">⚠️</div>
            <div class="notice-text">
              <strong>在开始刷图前请务必开启游戏内的日志功能！</strong>
            </div>
          </div>

          <!-- 教程 -->
          <div class="tutorial-section">
            <h4>🎮 开启日志功能教程</h4>
            <div class="steps">
              <div class="step">
                <span class="step-number">1</span>
                <span>打开游戏设置</span>
              </div>
              <div class="step">
                <span class="step-number">2</span>
                <span>选择"其他设置"</span>
              </div>
              <div class="step">
                <span class="step-number">3</span>
                <span>点击"开启日志"</span>
              </div>
              <div class="step">
                <span class="step-number">4</span>
                <span>看到"已开始日志"</span>
              </div>
              <div class="step">
                <span class="step-number">5</span>
                <span>点击"返回登录"</span>
              </div>
              <div class="step">
                <span class="step-number">6</span>
                <span>重新进入游戏</span>
              </div>
            </div>
            <p class="tutorial-tip">🔁 重新打开游戏需要再次开启日志功能</p>
          </div>

          <!-- 隐私说明 -->
          <div class="privacy-section">
            <h4>📊 数据隐私说明</h4>
            <p>本软件<strong>不会上传任何用户游戏内的数据</strong>。</p>
            <div class="network-ops">
              <div class="network-item">
                <span class="network-icon">⬇️</span>
                <span>拉取物品最新价格</span>
              </div>
              <div class="network-item">
                <span class="network-icon">⬆️</span>
                <span>上传物品最新价格（匿名）</span>
              </div>
            </div>
            <p class="offline-tip">💡 如反感联网操作，可断网使用（部分物品价格可能存在差异）</p>
          </div>

          <!-- 赞助区域 -->
          <div class="sponsor-section">
            <div class="sponsor-header">
              <h4>❤️ 赞助支持</h4>
              <span class="heart">💝</span>
            </div>
            <p class="sponsor-desc">如果这个工具对您有帮助，欢迎赞助支持作者的持续开发！</p>
            <div class="qrcode-container">
              <img :src="require('@/../public/assets/wtz.png')" alt="赞助二维码" class="qrcode">
            </div>
            <p class="sponsor-thanks">感谢您的支持！🎉</p>
          </div>
        </div>

        <div slot="footer" class="dialog-footer">
          <el-button type="primary" size="medium" @click="handleInstructionsClose">
            👍 我知道了
          </el-button>
        </div>
      </el-dialog>

      <!-- 日志提示框 - 带遮罩层防止点击 -->
      <div v-if="bagMgr.length === 0" class="alert-backdrop">
        <div class="alert-overlay">
          <div class="alert-container">
            <div class="alert-content">
              <i class="alert-icon">⚠️</i>
              <p class="alert-text">请开启日志后退出登录重新进入游戏！！！</p>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 简洁模式页面 -->
    <div v-if="isSimpleMode" class="simple-mode-container">
      <div class="simple-stats">
        <div class="stat-item">
          <span class="stat-label">已运行：</span>
          <span class="stat-value">{{ totalMinutes }}分{{ totalSeconds }}秒</span>
        </div>
        <div class="stat-item">
          <span class="stat-label">已掉落：</span>
          <span class="stat-value">{{ totalDropsValue.toFixed(0) }} <img :src="require('@/../public/assets/huo.png')"
              alt="火" class="simple-fire-icon"></span>
        </div>
        <div class="stat-item">
          <span class="stat-label">预测：</span>
          <span class="stat-value">{{ formattedHourlyRate }}火/时</span>
        </div>
      </div>

      <div class="simple-actions">
        <el-button @click="toggleSimpleMode" class="simple-btn" type="warning">
          关闭简洁模式
        </el-button>
      </div>
    </div>
  </div>
</template>

<script>
import TimeStats from './components/TimeStats.vue'
import ItemsPanel from './components/ItemsPanel.vue'
import ActionButtons from './components/ActionButtons.vue'
import AuthorDialog from './components/dialogs/AuthorDialog.vue'
import FilterDialog from './components/dialogs/FilterDialog.vue'
import SettingsDialog from './components/dialogs/SettingsDialog.vue'
import { dataService } from './services/dataService'
const { ipcRenderer } = window.require('electron')
const { dialog } = window.require('electron').remote

export default {
  components: {
    TimeStats,
    ItemsPanel,
    ActionButtons,
    AuthorDialog,
    FilterDialog,
    SettingsDialog
  },
  data() {
    return {
      // 开发者提示弹窗控制
      developerTipsVisible: true,
      dialogWidth: '80%', // 初始宽度
      // 背包管理
      bagMgr: [],
      tempBagData: {},
      isInitializingBag: false,

      // 免责声明相关
      disclaimerVisible: true,
      countdown: 10,
      countdownTimer: null,
      hasAcceptedDisclaimer: false,
      instructionsVisible: false,
      buttonsEnabled: false,

      // 应用状态
      currentTime: 0,
      totalTime: 0,
      items: [],
      allItems: [],
      mapCount: 0,
      priceData: {},
      isRunning: false,
      totalCost: 0,

      // 弹窗控制
      authorDialogVisible: false,
      filterDialogVisible: false,
      settingsDialogVisible: false,
      totalDropsVisible: false,

      // 过滤相关
      itemList: [],
      filteredItemsIds: [],

      // 设置相关
      costPerMap: 0,
      countIncome: true,
      opacity: 100,

      // 定时器
      timeInterval: null,
      totalTimer: null,

      // 检测相关状态
      isDetecting: true,
      detectFailed: false,
      logPath: '',
      isMonitoring: false,
      showTimeoutTip: false,
      detectionTimeout: null,
      detectionStartTime: null,

      // 地图状态管理
      isInMap: false,
      enterMapTime: 0,
      currentMapItems: [],
      isTrackingProfit: false,
      currentMapTime: 0,
      totalMapTime: 0,
      currentMapTimer: null,
      hasStartedTotalTimer: false,
      firstEnterMapTime: null,

      // 地图切换匹配规则
      enterMapFlag: "PageApplyBase@ _UpdateGameEnd: LastSceneName = World'/Game/Art/Maps/01SD/XZ_YuJinZhiXiBiNanSuo200/XZ_YuJinZhiXiBiNanSuo200.XZ_YuJinZhiXiBiNanSuo200' NextSceneName = World'/Game/Art/Maps",
      leaveMapFlag: "NextSceneName = World'/Game/Art/Maps/01SD/XZ_YuJinZhiXiBiNanSuo200/XZ_YuJinZhiXiBiNanSuo200.XZ_YuJinZhiXiBiNanSuo200'",
      logCache: '',

      appReady: false,

      // 物品掉落相关
      dropList: {},
      dropListAll: {},
      itemIdTable: {},
      pendingItems: {},
      logCacheTimer: null,

      currentProfitValue: 0,
      totalProfitValue: 0,
      isSimpleMode: false, // 简洁模式状态
      originalWindowSize: null
    }
  },
  computed: {
    hourlyRate() {
      return this.totalRate * 60;
    },
    formattedHourlyRate() {
      return Math.round(this.hourlyRate); // 四舍五入
    },
    // 总价值计算（保留3位小数）
    totalDropsValue() {
      return parseFloat(
        this.allDropsList.reduce((sum, item) => {
          return sum + (item.totalValue || 0);
        }, 0).toFixed(3)
      );
    },
    currentMinutes() {
      return Math.floor(this.currentMapTime / 60);
    },
    currentSeconds() {
      return this.currentMapTime % 60;
    },
    totalMinutes() {
      return Math.floor(this.totalMapTime / 60);
    },
    totalSeconds() {
      return this.totalMapTime % 60;
    },
    currentRate() {
      const currentValue = Object.entries(this.dropList).reduce((sum, [id, count]) => {
        return sum + (dataService.priceTable[id] || 0) * count;
      }, 0);
      const rate = this.currentMapTime > 0 ? (currentValue / (this.currentMapTime / 60)) : 0;
      return Math.floor(rate).toString();
    },
    totalRate() {
      const totalValue = Object.entries(this.dropListAll).reduce((sum, [id, count]) => {
        return sum + (dataService.priceTable[id] || 0) * count;
      }, 0);
      const rate = this.totalMapTime > 0 ? (totalValue / (this.totalMapTime / 60)) : 0;
      return Math.floor(rate).toString();
    },
    // 过滤后的物品列表（修正价值显示）
    filteredItems() {
      const merged = {};
      this.items
        .filter(item => !this.filteredItemsIds.includes(item.id))
        .forEach(item => {
          if (!merged[item.id]) {
            merged[item.id] = { ...item, count: 0, totalValue: 0 };
          }
          merged[item.id].count += item.count;
          merged[item.id].totalValue = parseFloat(
            (merged[item.id].totalValue + item.totalValue).toFixed(3)
          );
          merged[item.id].displayName = `${item.name} x${merged[item.id].count}`;
          merged[item.id].valueDisplay = merged[item.id].totalValue.toFixed(3);
        });
      return Object.values(merged);
    },
    allDropsList() {
      const merged = [];
      Object.entries(this.dropListAll).forEach(([id, count]) => {
        if (this.filteredItemsIds.includes(id)) return;

        const itemName = this.itemIdTable[id] || `未知物品(${id})`;
        const price = dataService.priceTable[id] || 0;
        const totalValue = parseFloat((price * count).toFixed(3));

        merged.push({
          id: id,
          name: itemName,
          count: count,
          price: price,
          totalValue: totalValue
        });
      });
      return merged;
    },
    currentProfit() {
      return this.currentProfitValue; // 直接返回数字
    },
    totalProfit() {
      return this.totalProfitValue; // 直接返回数字
    }
  },
  mounted() {
    // 绑定窗口尺寸变化监听（使用提前引入的 ipcRenderer）
    ipcRenderer.on('window-resize', this.handleWindowResize);
    // 初始化时调整一次
    this.adjustDialogWidth();

    const hasAccepted = localStorage.getItem('hasAcceptedDisclaimer');

    if (hasAccepted === 'true') {
      this.hasAcceptedDisclaimer = true;
      this.disclaimerVisible = false;
      this.setupBaseApp();
      // 已同意免责声明，直接显示开发者提示
      this.developerTipsVisible = true;
    } else {
      this.startCountdown();
    }

    this.setupBaseApp();
  },

  beforeDestroy() {
    this.stopAllIntervals();
    this.stopMonitoring();
    ipcRenderer.removeAllListeners();
    clearTimeout(this.logCacheTimer);

    if (this.detectionTimeout) clearTimeout(this.detectionTimeout);
    if (this.countdownTimer) clearInterval(this.countdownTimer);

    dataService.stopPriceSync();

    // 移除窗口尺寸监听
    ipcRenderer.removeListener('window-resize', this.handleWindowResize);
  },
  methods: {
    ...dataService.commonMethods,

    // 处理窗口尺寸变化
    handleWindowResize(width, height) {
      if (!this.isSimpleMode) {
        this.originalWindowSize = { width, height };
      }
    },

    // 切换简洁模式（强制尺寸更新版）
    toggleSimpleMode() {
      const { ipcRenderer } = window.require('electron');

      if (!this.isSimpleMode) {
        // 进入简洁模式：无论之前是否记录，强制获取当前尺寸并保存，然后强制设置为400x200
        ipcRenderer.invoke('get-window-size').then(currentSize => {
          this.originalWindowSize = currentSize; // 记录当前正常模式的尺寸
          // 强制设置简洁模式尺寸（加1再减1，解决Electron尺寸缓存问题） 宽 长
          ipcRenderer.send('set-window-size', 351, 266);
          setTimeout(() => {
            ipcRenderer.send('set-window-size', 350, 265);
          }, 50);
        });
      } else {
        // 退出简洁模式：恢复到之前记录的正常尺寸
        if (this.originalWindowSize) {
          // 同样强制刷新尺寸
          ipcRenderer.send('set-window-size',
            this.originalWindowSize.width + 1,
            this.originalWindowSize.height + 1
          );
          setTimeout(() => {
            ipcRenderer.send('set-window-size',
              this.originalWindowSize.width,
              this.originalWindowSize.height
            );
          }, 50);
        }
      }

      this.isSimpleMode = !this.isSimpleMode;
    },

    // 根据窗口宽度动态调整弹窗宽度
    adjustDialogWidth() {
      const windowWidth = window.innerWidth;
      if (windowWidth < 400) {
        this.dialogWidth = '95%'; // 窗口极窄时
      } else if (windowWidth < 600) {
        this.dialogWidth = '90%'; // 窗口较窄时
      } else {
        this.dialogWidth = '80%'; // 正常窗口
      }
    },

    // 处理成本更新
    handleCostUpdate(value) {
      // 将字符串转换为数字（确保类型正确）
      this.costPerMap = parseFloat(value) || 0;
      this.saveSettings(); // 保存设置
    },

    // 处理收益计算开关更新
    handleCountUpdate(checked) {
      this.countIncome = checked;
      this.saveSettings(); // 保存设置
    },

    // 处理透明度更新
    handleOpacityUpdate(value) {
      this.opacity = value;
      this.updateOpacity(value); // 调用已有的更新透明度方法
    },

    setupBaseApp() {
      dataService.disableWindowResize();
      this.hideScrollbar();
      this.loadSettings();
      this.loadItemList();
      this.loadPriceData();
      this.initItemData();

      dataService.startPriceSync(60000);
      setTimeout(() => {
        dataService.syncPricesFromServer();
      }, 2000);

      this.setupIpcListeners();
    },

    // 处理日志中的背包初始化数据
    processBagData(logContent) {
      if (logContent.includes('BagMgr@:InitBagData')) {
        this.isInitializingBag = true;
        const bagDataRegex = /BagMgr@:InitBagData PageId = (\d+) SlotId = (\d+) ConfigBaseId = (\d+) Num = (\d+)/g;
        let match;

        this.tempBagData = {};

        while ((match = bagDataRegex.exec(logContent)) !== null) {
          const pageId = parseInt(match[1], 10);
          const slotId = parseInt(match[2], 10);
          const configBaseId = match[3];
          const num = parseInt(match[4], 10);

          if (pageId === 102 || pageId === 103) {
            if (!this.tempBagData[configBaseId]) {
              this.tempBagData[configBaseId] = {
                slots: {},
                total: 0
              };
            }

            this.tempBagData[configBaseId].slots[slotId] = num;
            this.tempBagData[configBaseId].total += num;
          }
        }

        this.convertToBagMgr();
      }
    },

    // 转换临时数据为bagMgr格式
    convertToBagMgr() {
      if (Object.keys(this.itemIdTable).length === 0) {
        setTimeout(() => this.convertToBagMgr(), 100);
        return;
      }

      const newBagMgr = [];

      Object.entries(this.tempBagData).forEach(([code, data]) => {
        const itemInfo = this.fullTable[code] || {};

        newBagMgr.push({
          name: itemInfo.name || `未知物品(${code})`,
          code: code,
          type: itemInfo.type || '未知类型',
          price: itemInfo.price || 0,
          totalNum: data.total,
          slots: data.slots,
          initialTimestamp: Date.now()
        });
      });

      this.bagMgr = newBagMgr;
      this.isInitializingBag = false;
      console.log('背包初始化完成，物品数量:', this.bagMgr.length);
    },

    // 说明弹窗处理
    handleInstructionsClose() {
      this.instructionsVisible = false;
      this.buttonsEnabled = true;
    },
    showInstructions() {
      this.instructionsVisible = true;
    },

    // 免责声明相关
    startCountdown() {
      this.countdownTimer = setInterval(() => {
        if (this.countdown > 0) this.countdown--;
        else clearInterval(this.countdownTimer);
      }, 1000);
    },
    acceptDisclaimer() {
      if (this.countdown > 0) return;

      localStorage.setItem('hasAcceptedDisclaimer', 'true');
      this.hasAcceptedDisclaimer = true;
      this.disclaimerVisible = false;
      this.startDetection();
      // this.$message.success('感谢您的理解，祝您游戏愉快！');
      // 同意免责声明后显示开发者提示
      this.developerTipsVisible = true;
    },

    // 应用初始化
    initializeApp() {
      dataService.disableWindowResize();
      this.hideScrollbar();
      this.loadSettings();
      this.loadItemList();
      this.loadPriceData();
      this.initItemData();
      this.startDetection();

      dataService.startPriceSync(60000);
      setTimeout(() => {
        dataService.syncPricesFromServer();
      }, 2000);

      this.setupIpcListeners();
    },

    // IPC监听器设置
    setupIpcListeners() {
      ipcRenderer.on('app-ready', () => {
        console.log('App ready, checking disclaimer status...');
        this.appReady = true;

        if (this.hasAcceptedDisclaimer && !this.disclaimerVisible) {
          console.log('Already accepted disclaimer, starting detection...');
          setTimeout(() => {
            this.startDetection();
          }, 500);
        }
      });

      ipcRenderer.on('game-log-found', (event, path) => {
        this.handleDetectionSuccess();
        this.logPath = path;
        this.isDetecting = false;
        this.detectFailed = false;
        this.startMonitoring();
      });

      ipcRenderer.on('game-log-not-found', () => {
        if (this.detectionTimeout) clearTimeout(this.detectionTimeout);
        this.isDetecting = false;
        this.detectFailed = true;
      });

      ipcRenderer.on('log-content', (event, content) => {
        this.processLogContent(content);
      });

      ipcRenderer.on('log-error', (event, message) => {
        // this.$message.error(`日志错误: ${message}`);
      });
    },

    // 窗口控制
    minimizeWindow() {
      if (window.require) {
        ipcRenderer.send('window-minimize');
      }
    },
    closeWindow() {
      if (window.require) {
        const { ipcRenderer } = window.require('electron');
        console.log('渲染进程发送 window-close 事件');
        ipcRenderer.send('window-close');
      } else {
        console.error('window.require 不可用，无法发送事件');
      }
    },

    // 检测相关方法
    startDetection() {
      if (this.disclaimerVisible) {
        console.log('Disclaimer visible, skipping detection');
        return;
      }

      console.log('开始检测游戏进程...');
      this.isDetecting = true;
      this.detectFailed = false;
      this.showTimeoutTip = false;

      if (this.detectionTimeout) {
        clearTimeout(this.detectionTimeout);
      }

      this.detectionTimeout = setTimeout(() => {
        console.log('检测超时触发');
        this.handleDetectionTimeout();
      }, 5000);

      setTimeout(() => {
        if (this.isDetecting && !this.detectFailed) {
          console.log('显示超时提示');
          this.showTimeoutTip = true;
        }
      }, 3000);

      this.triggerDetection();
    },
    async triggerDetection() {
      try {
        console.log('=== 开始检测流程 ===');
        const logPath = await ipcRenderer.invoke('detect-game');
        if (logPath) {
          console.log('检测到游戏日志:', logPath);
          this.handleDetectionSuccess();
          this.logPath = logPath;
          this.isDetecting = false;
          this.detectFailed = false;
          this.startMonitoring();
        } else {
          console.log('未检测到游戏日志');
          this.handleDetectionTimeout();
        }
      } catch (error) {
        console.error('检测出错:', error);
        this.handleDetectionTimeout();
      }
    },
    handleDetectionTimeout() {
      if (this.isDetecting) {
        console.log('跳转到检测失败状态');
        this.isDetecting = false;
        this.detectFailed = true;
        this.showTimeoutTip = false;

        if (this.detectionTimeout) {
          clearTimeout(this.detectionTimeout);
          this.detectionTimeout = null;
        }

        this.$message.warning('自动检测超时，请尝试手动选择日志文件');
      }
    },
    handleDetectionSuccess() {
      if (this.detectionTimeout) {
        clearTimeout(this.detectionTimeout);
        this.detectionTimeout = null;
      }
      this.showTimeoutTip = false;
      console.log('检测成功，清理超时计时器');
    },
    async retryDetection() {
      this.startDetection();
      this.$message.info('正在重新检测...');

      try {
        const logPath = await ipcRenderer.invoke('detect-game');
        if (logPath) {
          this.handleDetectionSuccess();
          this.logPath = logPath;
          this.isDetecting = false;
          this.detectFailed = false;
          this.startMonitoring();
          this.$message.success('检测成功！');
        } else {
          this.isDetecting = false;
          this.detectFailed = true;
          this.$message.error('未检测到游戏进程，请确保游戏已启动');
        }
      } catch (error) {
        this.isDetecting = false;
        this.detectFailed = true;
        // this.$message.error(`检测出错: ${error.message}`);
      }
    },
    manualSelectLog() {
      dialog.showOpenDialog({
        title: '选择游戏日志文件',
        filters: [{ name: '日志文件', extensions: ['log'] }],
        properties: ['openFile']
      }).then(result => {
        if (!result.canceled && result.filePaths.length) {
          this.logPath = result.filePaths[0];
          this.isDetecting = false;
          this.detectFailed = false;
          // this.$message.success('已选择日志文件');
          this.startMonitoring();
        }
      });
    },

    // 日志监控
    startMonitoring() {
      if (this.isMonitoring) return;
      this.isMonitoring = true;
      ipcRenderer.send('set-log-path', this.logPath);
      ipcRenderer.send('start-monitoring');
    },
    stopMonitoring() {
      if (!this.isMonitoring) return;
      this.isMonitoring = false;
      ipcRenderer.send('stop-monitoring');
    },

    // 计时器管理
    startTotalTimer() {
      if (this.totalTimer) clearInterval(this.totalTimer);

      this.totalTimer = setInterval(() => {
        this.totalMapTime++;
      }, 1000);
      this.hasStartedTotalTimer = true;
    },
    stopAllIntervals() {
      clearInterval(this.timeInterval);
      clearInterval(this.totalTimer);
      this.timeInterval = null;
      this.totalTimer = null;
      this.stopCurrentMapTimer();
      this.isTrackingProfit = false;
      this.hasStartedTotalTimer = false;
    },

    // 日志处理
    processLogContent(content) {
      this.logCache += content;
      dataService.processPriceInfo(content);

      // 处理背包初始化数据
      if (content.includes('BagMgr@:InitBagData')) {
        this.processBagData(content);
      }

      // 只判断是否为PickItems类型，其他所有类型都按非掉落处理
      const isPickItems = content.includes('ItemChange@ ProtoName=PickItems');

      // 处理物品删除（如交易行上架）
      if (content.includes('ItemChange@ Delete Id=')) {
        this.processItemDeletion(content);
      }

      // 处理背包物品修改，传入是否为掉落类型的标记
      if (content.includes('BagMgr@:Modfy BagItem')) {
        this.processItemDrops(content, isPickItems);
      }

      // 地图进入/离开检测（保持不变）
      if (this.logCache.includes(this.enterMapFlag)) {
        this.handleEnterMap();
        this.logCache = '';
        return;
      }

      if (this.logCache.includes(this.leaveMapFlag)) {
        this.handleLeaveMap();
        this.logCache = '';
        return;
      }

      clearTimeout(this.logCacheTimer);
      this.logCacheTimer = setTimeout(() => {
        this.logCache = '';
      }, 10000);
    },

    // 新增处理物品删除的方法
    processItemDeletion(content) {
      console.log('开始处理物品删除记录');
      const lines = content.split('\n');
      const deletePattern = /ItemChange@ Delete Id=([\d_]+) in PageId=(\d+) SlotId=(\d+)/;

      lines.forEach(line => {
        const match = line.match(deletePattern);
        if (match) {
          const fullId = match[1];
          // 从ID中提取物品配置ID（类似100300_8636107b...中的100300）
          const configBaseId = fullId.split('_')[0];
          const pageId = parseInt(match[2], 10);
          const slotId = parseInt(match[3], 10);

          console.log(`检测到物品删除: 配置ID=${configBaseId}, 页=${pageId}, 槽位=${slotId}`);

          // 只处理目标页的物品
          if (pageId === 102 || pageId === 103) {
            this.removeItemFromBag(configBaseId, slotId);
          }
        }
      });
    },

    // 新增从背包移除物品的方法
    removeItemFromBag(configBaseId, slotId) {
      const itemIndex = this.bagMgr.findIndex(item => item.code === configBaseId);

      if (itemIndex !== -1) {
        const bagItem = this.bagMgr[itemIndex];
        const slotKey = slotId.toString();

        // 如果该槽位存在，则移除
        if (bagItem.slots.hasOwnProperty(slotKey)) {
          const removedCount = bagItem.slots[slotKey];
          delete bagItem.slots[slotKey];

          // 重新计算总数量
          bagItem.totalNum = Object.values(bagItem.slots).reduce((sum, num) => sum + num, 0);

          console.log(`从背包移除物品 ${configBaseId} 的槽位 ${slotId}，数量: ${removedCount}`);

          // 如果物品总数量为0，从背包中彻底移除
          if (bagItem.totalNum === 0) {
            this.bagMgr.splice(itemIndex, 1);
            console.log(`物品 ${configBaseId} 数量为0，已从背包中移除`);
          } else {
            this.$set(this.bagMgr, itemIndex, bagItem);
          }
        }
      }
    },

    // 运行控制
    startRunning() {
      if (this.isRunning) return;
      this.isRunning = true;
      this.isTrackingProfit = true;
    },
    clearItemsPanel() {
      this.items = [];
      this.dropList = {};
      this.$message.success('已清空当前掉落面板');
    },
    showTotalDrops() {
      this.totalDropsVisible = true;
    },

    // 数据加载
    async loadPriceData() {
      this.priceData = await dataService.loadItemJson();
    },
    async loadItemList() {
      try {
        console.log('开始加载物品列表...');
        const itemData = await dataService.loadItemJson(); // 获取原始对象数据

        // 关键：将对象转换为数组（必须做这一步）
        this.itemList = Object.entries(itemData).map(([id, item]) => ({
          id: id,  // 保留原键作为id
          ...item  // 展开物品属性（name, type, price等）
        }));

        console.log('物品列表加载完成:', this.itemList.length, '个物品');
      } catch (error) {
        console.error('加载物品列表失败:', error);
        this.itemList = []; // 出错时仍返回空数组
      }
    },

    // 设置相关
    loadSettings() {
      const settings = dataService.loadSettings();
      this.costPerMap = settings.costPerMap || 0;
      this.countIncome = settings.countIncome !== undefined ? settings.countIncome : true;
      this.opacity = settings.opacity || 100;
      this.filteredItemsIds = settings.filteredItemsIds || [];
      dataService.applyWindowOpacity(this.opacity);
    },
    saveSettings() {
      dataService.saveSettings({
        costPerMap: this.costPerMap,
        countIncome: this.countIncome,
        opacity: this.opacity,
        filteredItemsIds: this.filteredItemsIds
      });
    },
    updateOpacity(val) {
      this.opacity = val;
      this.saveSettings();
      dataService.applyWindowOpacity(val);
    },

    // 物品数据处理
    async initItemData() {
      try {
        this.fullTable = await dataService.loadItemJson();
        this.itemIdTable = {};
        dataService.priceTable = {};

        Object.keys(this.fullTable).forEach(id => {
          this.itemIdTable[id] = this.fullTable[id].name || `未知物品(${id})`;
          // 确保价格为数字类型
          dataService.priceTable[id] = parseFloat(this.fullTable[id].price) || 0;
        });

        console.log('物品数据加载完成，共', Object.keys(this.fullTable).length, '种物品');
      } catch (error) {
        console.error('初始化物品数据失败:', error);
        this.itemIdTable = {};
        dataService.priceTable = {};
        this.fullTable = {};
      }
    },

    // 处理物品掉落
    // 修改processItemDrops方法，接收是否为掉落类型的参数
    processItemDrops(content, isPickItems) {
      console.log(`开始处理物品变动，是否为掉落: ${isPickItems}，内容包含修改记录:`, content.includes('BagMgr@:Modfy BagItem'));
      console.log('当前地图状态:', this.isInMap, '追踪状态:', this.isTrackingProfit);
      const modifications = this.scanBagModifications(content);
      console.log('解析到的物品修改记录数量:', modifications.length);

      if (modifications.length === 0) return;

      const targetModifications = modifications.filter(
        item => item.pageId === 102 || item.pageId === 103
      );
      console.log('过滤后（102/103页）的记录数量:', targetModifications.length);

      // 处理每个修改记录，传入是否为掉落类型的标记
      targetModifications.forEach(mod => this.handleBagModification(mod, isPickItems));
    },

    // 扫描日志中的背包修改记录
    scanBagModifications(logText) {
      const lines = logText.split('\n');
      const modifications = [];
      const pattern = /BagMgr@:Modfy BagItem PageId = (\d+) SlotId = (\d+) ConfigBaseId = (\d+) Num = (\d+)/;

      lines.forEach(line => {
        const match = line.match(pattern);
        if (match) {
          modifications.push({
            pageId: parseInt(match[1], 10),
            slotId: parseInt(match[2], 10),
            configBaseId: match[3],
            num: parseInt(match[4], 10)
          });
        }
      });

      return modifications;
    },

    // 修改handleBagModification方法，根据是否为掉落类型决定是否记录
    handleBagModification(mod, isPickItems) {
      console.log(`处理物品修改记录: ${JSON.stringify(mod)}，是否为掉落: ${isPickItems}`);

      if (![102, 103].includes(mod.pageId)) {
        console.log('跳过非目标页（102/103）的记录');
        return;
      }

      const itemIndex = this.bagMgr.findIndex(item => item.code === mod.configBaseId);
      console.log(`物品 ${mod.configBaseId} 在bagMgr中的索引:`, itemIndex);

      // 无论是否为掉落，都需要更新背包数量
      let needUpdateBag = true;
      // 只有是PickItems时才记录掉落
      let shouldRecordDrop = isPickItems;

      if (itemIndex !== -1) {
        // 已有物品的处理逻辑
        const bagItem = this.bagMgr[itemIndex];
        const slotId = mod.slotId.toString();
        console.log(`物品 ${mod.configBaseId} 的${slotId}位置原始数量:`, bagItem.slots[slotId]);

        if (bagItem.slots.hasOwnProperty(slotId)) {
          const originalNum = bagItem.slots[slotId];
          const newNum = mod.num;
          const changeNum = newNum - originalNum;
          console.log(`数量变化: 原始${originalNum} → 新值${newNum}，变动数量:${changeNum}`);

          // 如果是掉落类型且数量增加，记录掉落
          if (shouldRecordDrop && changeNum > 0) {
            this.recordPickedItem(mod.configBaseId, changeNum);
          }

          // 更新背包数量
          bagItem.slots[slotId] = newNum;
          bagItem.totalNum = Object.values(bagItem.slots).reduce((sum, num) => sum + num, 0);
          this.$set(this.bagMgr, itemIndex, bagItem);
          console.log(`已更新物品 ${mod.configBaseId} 的数量`);
        } else {
          // 新位置但物品已存在的情况
          console.log(`物品 ${mod.configBaseId} 的${slotId}位置无记录，新增位置数据`);
          if (mod.num > 0) {
            // 如果是掉落类型，记录新增的数量
            if (shouldRecordDrop) {
              this.recordPickedItem(mod.configBaseId, mod.num);
            }
            bagItem.slots[slotId] = mod.num;
            bagItem.totalNum = Object.values(bagItem.slots).reduce((sum, num) => sum + num, 0);
            this.$set(this.bagMgr, itemIndex, bagItem);
          }
        }
      } else if (mod.num > 0) {
        // 全新物品的处理
        console.log(`发现新物品 ${mod.configBaseId}，添加到bagMgr`);
        const itemInfo = this.fullTable[mod.configBaseId] || {};

        // 如果是掉落类型，记录掉落
        if (shouldRecordDrop) {
          this.recordPickedItem(mod.configBaseId, mod.num);
        }

        // 添加到背包
        this.bagMgr.push({
          name: itemInfo.name || `未知物品(${mod.configBaseId})`,
          code: mod.configBaseId,
          type: itemInfo.type || '未知类型',
          price: itemInfo.price || 0,
          totalNum: mod.num,
          slots: { [mod.slotId]: mod.num },
          initialTimestamp: Date.now()
        });
      }
    },

    // 记录拾取的物品
    recordPickedItem(code, count) {
      const itemInfo = this.fullTable[code] || {};
      const itemPrice = dataService.priceTable[code] || 0;
      // 计算总价值并保留3位小数
      const totalValue = parseFloat((itemPrice * count).toFixed(3));

      const item = {
        id: code,
        name: itemInfo.name || `未知物品(${code})`,
        count: count,
        price: itemPrice,
        totalValue: totalValue, // 用于显示的总价值
        timestamp: new Date().getTime()
      };

      this.items.push(item);
      console.log(`拾取: ${item.name} x${count}，价值: ${totalValue}`);

      this.updateDropStatistics(code, count);
    },

    // 更新掉落统计数据
    updateDropStatistics(code, count) {
      // 更新当前地图掉落
      if (!this.dropList[code]) {
        this.$set(this.dropList, code, 0);
      }
      this.dropList[code] += count;

      // 更新总掉落
      if (!this.dropListAll[code]) {
        this.$set(this.dropListAll, code, 0);
      }
      this.dropListAll[code] += count;

      // 更新收益
      this.updateProfitImmediately();
    },
    dealDrop(dropData) {
      this.invokeDropItemsRecursive(dropData);
      this.updateDropPanel();
    },

    invokeDropItemsRecursive(data) {
      for (const [key, value] of Object.entries(data)) {
        if (typeof value === 'object' && value !== null && 'item' in value) {
          const hasPicked = 'Picked' in value ||
            (typeof value.item === 'object' && value.item !== null && 'Picked' in value.item);

          if (hasPicked) this.invokeDropItemProcessing(value);
        }

        if (typeof value === 'object' && value !== null) {
          this.invokeDropItemsRecursive(value);
        }
      }
    },

    invokeDropItemProcessing(itemData) {
      let picked = false;
      if ('Picked' in itemData) picked = itemData.Picked;
      else if (typeof itemData.item === 'object' && itemData.item !== null && 'Picked' in itemData.item) {
        picked = itemData.item.Picked;
      }
      if (!picked) return;

      let itemInfo = itemData.item || {};
      if (typeof itemInfo === 'object' && itemInfo !== null && 'SpecialInfo' in itemInfo) {
        const specialInfo = itemInfo.SpecialInfo;
        if (typeof specialInfo === 'object' && specialInfo !== null) {
          if ('BaseId' in specialInfo) itemInfo.BaseId = specialInfo.BaseId;
          if ('Num' in specialInfo) itemInfo.Num = specialInfo.Num;
        }
      }

      const baseId = itemInfo.BaseId;
      const num = itemInfo.Num || 1;
      if (baseId === undefined || baseId === null) return;

      const baseIdStr = String(baseId);
      let itemName = this.itemIdTable[baseIdStr] || baseIdStr;

      if (this.filteredItemsIds.includes(baseIdStr)) return;

      if (!this.itemIdTable[baseIdStr]) {
        if (!this.pendingItems[baseIdStr]) this.pendingItems[baseIdStr] = 0;
        this.pendingItems[baseIdStr] += num;
        return;
      }

      if (!this.dropList[baseIdStr]) this.$set(this.dropList, baseIdStr, 0);
      this.dropList[baseIdStr] += num;

      if (!this.dropListAll[baseIdStr]) this.$set(this.dropListAll, baseIdStr, 0);
      this.dropListAll[baseIdStr] += num;

      const newItem = {
        id: baseIdStr,
        name: itemName,
        count: num,
        price: dataService.priceTable[baseIdStr] || 0,
        totalValue: parseFloat((dataService.priceTable[baseIdStr] * num).toFixed(3)),
        timestamp: new Date().getTime()
      };

      this.items.push(newItem);
      this.updateProfitImmediately();
    },

    // 更新收益（保留3位小数）
    updateProfitImmediately() {
      const currentValue = Object.entries(this.dropList).reduce((sum, [id, count]) => {
        return sum + (dataService.priceTable[id] || 0) * count;
      }, 0);

      const totalValue = Object.entries(this.dropListAll).reduce((sum, [id, count]) => {
        return sum + (dataService.priceTable[id] || 0) * count;
      }, 0);

      this.currentProfitValue = parseFloat((currentValue - parseFloat(this.costPerMap || 0)).toFixed(3));
      this.totalProfitValue = parseFloat((totalValue - this.totalCost).toFixed(3));
    },

    updateDropPanel() {
      console.log('当前地图掉落更新:', this.dropList);
    },

    // 弹窗控制
    showAuthor() { this.authorDialogVisible = true; },
    showFilter() { this.filterDialogVisible = true; },
    showLog() { this.$message.info('日志功能'); },
    showSettings() { this.settingsDialogVisible = true; },
    updateFilter(ids) {
      this.filteredItemsIds = ids;
      this.saveSettings();
    },

    // 地图事件处理
    handleEnterMap() {
      if (!this.isInMap) {
        this.isInMap = true;
        this.enterMapTime = Date.now();
        this.currentMapItems = [];
        this.mapCount++;

        if (!this.hasStartedTotalTimer) {
          this.firstEnterMapTime = Date.now();
          this.startTotalTimer();
        }

        if (!this.isTrackingProfit) this.isTrackingProfit = true;

        this.startCurrentMapTimer();

        if (this.isTrackingProfit) {
          this.totalCost += parseFloat(this.costPerMap) || 0;
        }

        this.dropList = {};
        this.items = [];
        this.currentProfitValue = -parseFloat(this.costPerMap || 0);

        const totalValue = Object.entries(this.dropListAll).reduce((sum, [id, count]) => {
          return sum + (dataService.priceTable[id] || 0) * count;
        }, 0);
        this.totalProfitValue = parseFloat((totalValue - this.totalCost).toFixed(3));

        // this.$message.info(`进入新地图（第${this.mapCount}张）`);
      }
    },
    startCurrentMapTimer() {
      if (this.currentMapTimer) clearInterval(this.currentMapTimer);
      this.currentMapTimer = setInterval(() => {
        this.currentMapTime++;
      }, 1000);
    },
    stopCurrentMapTimer() {
      if (this.currentMapTimer) {
        clearInterval(this.currentMapTimer);
        this.currentMapTimer = null;
      }
    },
    handleLeaveMap() {
      if (this.isInMap) {
        this.isInMap = false;
        this.stopCurrentMapTimer();

        const mapProfit = this.currentProfit;
        // this.$message.success(`地图结束：耗时${Math.floor(this.currentMapTime / 60)}分${this.currentMapTime % 60}秒，收益${mapProfit}`);

        this.currentMapTime = 0;
        this.items = [];
        this.dropList = {};
        this.currentProfitValue = 0;
      }
    }
  }
}
</script>

<style scoped>
/* 开发者提示弹窗样式 - 添加内边距和隐藏滚动条 */
.developer-tips-dialog .el-dialog__body {
  padding: 20px !important;
  /* 添加内边距，距离边缘有距离 */
  max-height: 50vh;
  overflow: hidden !important;
  /* 隐藏溢出内容 */
}

.developer-tips-content {
  max-height: 60vh;
  padding-right: 8px;
  margin-right: -8px;
  overflow-y: auto;
  overflow-x: hidden;

  /* 彻底隐藏滚动条 */
  scrollbar-width: none;
  -ms-overflow-style: none;
}

/* 针对 Webkit 浏览器的滚动条隐藏 */
.developer-tips-content::-webkit-scrollbar {
  width: 0;
  height: 0;
  background: transparent;
}

.developer-tips-content::-webkit-scrollbar-thumb {
  background: transparent;
}

.developer-tips-content::-webkit-scrollbar-track {
  background: transparent;
}

/* 确保弹窗内容不会超出 */
.developer-tips-dialog {
  border-radius: 8px;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
  transition: width 0.3s ease;
  overflow: hidden;
  /* 防止内容溢出弹窗 */
}

/* 内容区域自适应 */
.developer-tips-content {
  padding: 10px;
  box-sizing: border-box;
}

/* 窗口宽度较小时的适配 */
@media (max-width: 600px) {
  .developer-tips-dialog {
    width: 90% !important;
    /* 窗口较窄时占比更大 */
  }

  .tips-section p {
    font-size: 12px;
    /* 缩小字体避免换行过多 */
  }
}

/* 确保内容不会超出弹窗 */
.developer-tips-content {
  max-height: 70vh;
  overflow-y: auto;
  padding-right: 10px;
}

.developer-tips-dialog .el-dialog__header {
  padding: 18px 20px;
  border-bottom: 1px solid #f0f0f0;
}

.developer-tips-dialog .el-dialog__title {
  color: #333;
  font-size: 18px;
  font-weight: 600;
}

.tips-header {
  display: flex;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px dashed #eee;
}

.tips-icon {
  font-size: 24px;
  margin-right: 10px;
}

.tips-header h3 {
  margin: 0;
  color: #42b983;
  font-size: 16px;
}

.tips-sections {
  margin-top: 10px;
  line-height: 1.8;
}

.tips-section {
  margin-bottom: 15px;
  padding: 10px;
  border-radius: 4px;
  background-color: #f9f9f9;
}

.tips-section h4 {
  margin: 0 0 8px 0;
  color: #333;
  font-size: 14px;
  font-weight: 600;
}

.tips-section p {
  margin: 0 0 5px 0;
  color: #666;
  font-size: 13px;
}

.warning-section {
  border-left: 3px solid #faad14;
  background-color: #fffbe6;
}

.link {
  color: #42b983;
  text-decoration: underline;
  cursor: pointer;
}

.link:hover {
  color: #359e75;
}

.tips-footer {
  text-align: center;
  padding: 15px 20px;
  border-top: 1px solid #f0f0f0;
}

.confirm-btn {
  width: 140px;
  height: 40px;
  font-size: 14px;
  background-color: #42b983;
  border-color: #42b983;
}

.confirm-btn:hover {
  background-color: #359e75;
  border-color: #359e75;
}

.instructions-content {
  max-height: 60vh;
  padding-right: 8px;
  /* 为滚动条预留空间 */
  margin-right: -8px;
  /* 抵消预留空间 */
  overflow-y: auto;
  overflow-x: hidden;

  /* 彻底隐藏滚动条 */
  scrollbar-width: none;
  -ms-overflow-style: none;
}


/* 针对 Webkit 浏览器的滚动条隐藏 */
.instructions-content::-webkit-scrollbar {
  width: 0;
  height: 0;
  background: transparent;
}

.instructions-content::-webkit-scrollbar-thumb {
  background: transparent;
}

.instructions-content::-webkit-scrollbar-track {
  background: transparent;
}

/* 重要提示 */
.important-notice {
  display: flex;
  align-items: flex-start;
  background: linear-gradient(135deg, #fff3e0, #ffe0b2);
  border: 2px solid #ff9800;
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 20px;
}


.notice-icon {
  font-size: 24px;
  margin-right: 12px;
  flex-shrink: 0;
}

.notice-text {
  color: #e65100;
  font-size: 15px;
  line-height: 1.4;
}

/* 隐私说明 */
.privacy-section {
  background: #f8f9fa;
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 20px;
  border-left: 4px solid #2196f3;
}

.privacy-section h4 {
  color: #1976d2;
  margin-bottom: 12px;
  font-size: 16px;
}

.network-ops {
  margin: 15px 0;
}

.network-item {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  padding: 8px 12px;
  background: white;
  border-radius: 8px;
  border: 1px solid #e0e0e0;
}

.network-icon {
  margin-right: 10px;
  font-size: 16px;
}

.offline-tip {
  background: #e8f5e8;
  padding: 10px 12px;
  border-radius: 8px;
  border-left: 3px solid #4caf50;
  margin-top: 12px;
  font-size: 14px;
}

/* 教程 */
.tutorial-section {
  background: #f0f9ff;
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 20px;
  border-left: 4px solid #00bcd4;
}

.tutorial-section h4 {
  color: #00838f;
  margin-bottom: 15px;
  font-size: 16px;
}

.steps {
  margin: 15px 0;
}

.step {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  padding: 10px 12px;
  background: white;
  border-radius: 8px;
  border: 1px solid #b3e5fc;
}

.step-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  background: #00bcd4;
  color: white;
  border-radius: 50%;
  font-size: 12px;
  font-weight: bold;
  margin-right: 12px;
  flex-shrink: 0;
}

.tutorial-tip {
  background: #e1f5fe;
  padding: 10px 12px;
  border-radius: 8px;
  border-left: 3px solid #00bcd4;
  margin-top: 12px;
  font-size: 14px;
  color: #006064;
}

/* 赞助区域 */
.sponsor-section {
  background: linear-gradient(135deg, #fff8e1, #ffecb3);
  border-radius: 12px;
  padding: 20px;
  text-align: center;
  border: 2px dashed #ffc107;
}

.sponsor-header {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-bottom: 10px;
}

.sponsor-header h4 {
  color: #ff6f00;
  margin: 0;
  font-size: 16px;
}

.heart {
  font-size: 18px;
}

.sponsor-desc {
  color: #666;
  margin-bottom: 15px;
  font-size: 14px;
}

.qrcode-container {
  margin: 15px 0;
}

.qrcode {
  max-width: 180px;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border: 3px solid white;
}

.sponsor-thanks {
  color: #ff6f00;
  font-weight: 500;
  margin-top: 10px;
}

.dialog-footer {
  text-align: center;
  padding-top: 10px;
  border-top: 1px solid #f0f0f0;
}


.instructions-text {
  margin-bottom: 20px;
}

.instructions-text p {
  margin-bottom: 10px;
  line-height: 1.5;
}

.instructions-text ul {
  margin: 10px 0;
  padding-left: 20px;
}

.instructions-text li {
  margin-bottom: 5px;
}

.log-tutorial {
  background: #f0f9ff;
  padding: 15px;
  border-radius: 6px;
  border-left: 4px solid #409eff;
  margin: 15px 0;
}

.log-tutorial .tip {
  font-size: 12px;
  color: #666;
  margin-top: 5px;
}

.sponsor-section {
  text-align: center;
  border-top: 1px solid #e0e0e0;
  padding-top: 20px;
  margin-top: 20px;
}

.sponsor-section h3 {
  margin-bottom: 10px;
  color: #333;
}

.qrcode-container {
  margin: 15px 0;
}

.qrcode {
  max-width: 200px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.sponsor-tip {
  color: #666;
  font-size: 14px;
}

.dialog-footer {
  text-align: center;
}

/* 基础样式 */
#app {
  height: 100vh;
  width: 100vw;
  margin: 0;
  padding: 0;
  background: #f5f5f5;
  overflow: hidden;
  position: fixed;
  top: 0;
  left: 0;
}

/* 标题栏样式 */
.custom-titlebar {
  height: 40px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 15px;
  font-family: 'Microsoft YaHei', sans-serif;
  -webkit-app-region: drag;
  user-select: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  position: relative;
  z-index: 1000;
}

.title-content {
  display: flex;
  align-items: center;
  gap: 10px;
}

.title-text {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
}

.main-title {
  font-size: 14px;
  font-weight: 600;
}

.sub-title {
  font-size: 10px;
  opacity: 0.8;
}

.titlebar-buttons {
  display: flex;
  gap: 8px;
  -webkit-app-region: no-drag;
}

.titlebar-btn {
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  color: white;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.titlebar-btn:hover {
  background: rgba(255, 255, 255, 0.1);
}

.close-btn:hover {
  background: #ff4757;
}

.fire-icon {
  font-size: 18px;
}

/* 主内容区域 */
.main-content {
  height: calc(100vh - 40px);
  display: flex;
  flex-direction: column;
  padding: 15px;
  box-sizing: border-box;
  overflow: hidden;
}

.top-section {
  flex-shrink: 0;
  margin-bottom: 15px;
}

.scroll-section {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
  margin: 10px 0;
}

.scroll-section::-webkit-scrollbar {
  width: 0 !important;
  display: none;
}

.bottom-section {
  flex-shrink: 0;
  margin-top: auto;
  padding-top: 10px;
}

.divider {
  height: 1px;
  background: #e0e0e0;
  margin: 10px 0;
}

/* 回本状态 */
.break-even-section {
  display: flex;
  align-items: center;
  margin: 15px 0;
  padding: 0 10px;
}

.divider-line {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, #e0e0e0, transparent);
}

.break-even-text {
  padding: 0 15px;
  color: #67C23A;
  font-weight: bold;
  font-size: 14px;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 5px;
}

.rate-icon {
  width: 16px;
  height: 16px;
}

/* 检测状态 */
.detection-status {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: calc(100vh - 40px);
  background: linear-gradient(135deg, #f5f7fa 0%, #e4e7ed 100%);
  padding: 20px;
}

.spinner {
  width: 50px;
  height: 50px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #42b983;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 20px;
}

.detection-status p {
  font-size: 16px;
  color: #606266;
  margin: 0;
}

.timeout-tip {
  font-size: 14px !important;
  color: #e6a23c !important;
  margin-top: 10px !important;
  animation: fadeIn 0.5s ease-in;
}

/* 检测失败样式 */
.detection-error-container {
  display: flex;
  align-items: center;
  justify-content: center;
  height: calc(100vh - 40px);
  background: linear-gradient(135deg, #f5f7fa 0%, #e4e7ed 100%);
  padding: 20px;
}

.detection-error-card {
  background: white;
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  padding: 40px;
  max-width: 500px;
  width: 100%;
  text-align: center;
  border: 1px solid #e1e8ed;
  animation: fadeInUp 0.6s ease-out;
}

.error-icon-wrapper {
  margin-bottom: 24px;
}

.error-icon {
  width: 80px;
  height: 80px;
  background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%);
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 20px rgba(244, 67, 54, 0.3);
}

.error-icon i {
  font-size: 36px;
  color: white;
}

.error-content {
  margin-bottom: 10px;
}

.error-title {
  font-size: 22px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 12px;
  line-height: 1.4;
}

.path-info-section {
  background: #f8f9fa;
  border-radius: 12px;
  padding: 20px;
  border: 1px solid #e9ecef;
  text-align: left;
}

.path-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  font-size: 14px;
  color: #495057;
  font-weight: 500;
}

.path-header i {
  color: #409eff;
}

.path-content {
  background: white;
  border-radius: 8px;
  padding: 12px 16px;
  border: 1px solid #e1e8ed;
  margin-bottom: 12px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
}

.path-content code {
  color: #e83e8c;
  font-size: 13px;
  word-break: break-all;
  line-height: 1.5;
}

.path-tip {
  font-size: 12px;
  color: #6c757d;
  margin: 0;
  line-height: 1.5;
}

.action-buttons {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  width: 100%;
  max-width: 320px;
  margin: 0 auto;
}

.retry-btn,
.manual-btn {
  height: 44px;
  padding: 12px 20px;
  border-radius: 8px;
  font-weight: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

.retry-btn .el-icon-refresh,
.manual-btn .el-icon-folder-opened {
  margin-right: 6px;
  font-size: 16px;
}

.retry-btn span,
.manual-btn span {
  display: flex;
  align-items: center;
  justify-content: center;
}

.manual-btn:hover {
  border-color: #409eff;
  color: #409eff;
  background: #ecf5ff;
}

/* 免责声明样式 */
.disclaimer-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.disclaimer-container {
  background: white;
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
  width: 100%;
  max-width: 800px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.disclaimer-header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 20px 30px;
  text-align: center;
}

.disclaimer-header h2 {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
}

.disclaimer-content {
  flex: 1;
  overflow-y: auto;
  padding: 30px;
  max-height: 60vh;
  /* 隐藏滚动条但保持滚动功能 */
  scrollbar-width: none;
  /* Firefox */
  -ms-overflow-style: none;
  /* IE and Edge */
}

.disclaimer-content::-webkit-scrollbar {
  display: none;
  /* Chrome, Safari and Opera */
}

.disclaimer-text h3 {
  color: #e6a23c;
  margin-bottom: 20px;
  text-align: center;
  font-size: 18px;
  border-bottom: 2px solid #e6a23c;
  padding-bottom: 10px;
}

.disclaimer-text h4 {
  color: #409eff;
  margin: 25px 0 15px 0;
  border-left: 4px solid #409eff;
  padding-left: 12px;
  font-size: 16px;
}

.disclaimer-text p {
  line-height: 1.7;
  margin-bottom: 15px;
  /* color: #606266; */
  /* font-size: 14px; */
}

.disclaimer-text ul {
  padding-left: 24px;
  margin-bottom: 20px;
}

.disclaimer-text li {
  line-height: 1.7;
  margin-bottom: 10px;
  color: #606266;
  font-size: 14px;
}

.countdown-section {
  background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);
  border: 2px solid #ff9800;
  border-radius: 8px;
  padding: 20px;
  margin-top: 30px;
  text-align: center;
}

.countdown-text {
  margin: 0;
  font-size: 20px;
  color: #ff0800;
  font-weight: 500;
}

.countdown-number {
  color: #f44336;
  font-weight: bold;
  font-size: 18px;
  margin: 0 5px;
}

.disclaimer-footer {
  background: #f8f9fa;
  padding: 20px 30px;
  text-align: center;
  border-top: 1px solid #e9ecef;
}

.accept-btn {
  width: 200px;
  height: 44px;
  font-size: 16px;
  font-weight: 500;
}

.accept-btn:disabled {
  background-color: #c0c4cc;
  border-color: #c0c4cc;
  color: #fff;
  cursor: not-allowed;
}

/* 弹窗样式修复 */
::v-deep .el-dialog {
  position: fixed !important;
  top: 40% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  z-index: 9999 !important;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1) !important;
  border-radius: 6px !important;
  width: 90% !important;
  max-width: 400px !important;
}

::v-deep .total-drops-dialog .el-dialog__body {
  padding: 0 !important;
  max-height: 70vh;
  overflow: hidden;
}

::v-deep .total-drops-dialog .dialog-content {
  max-height: 70vh;
  overflow-y: auto;
  padding: 15px;
}

::v-deep .total-drops-dialog .dialog-content::-webkit-scrollbar {
  width: 0 !important;
  display: none;
}

::v-deep .total-drops-dialog .dialog-content {
  -ms-overflow-style: none;
  scrollbar-width: none;
}

::v-deep .total-drops-dialog .total-drops-table {
  width: 100%;
}

::v-deep .total-drops-dialog .total-drops-table .el-table__body-wrapper {
  max-height: 60vh;
  overflow-y: auto;
}

::v-deep .total-drops-dialog .total-drops-table .el-table__body-wrapper::-webkit-scrollbar {
  width: 0 !important;
  display: none;
}

::v-deep .total-drops-dialog .total-drops-table .el-table__body-wrapper {
  -ms-overflow-style: none;
  scrollbar-width: none;
}

/* 动画 */
@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 滚动条样式 */
.disclaimer-content::-webkit-scrollbar {
  width: 8px;
}

.disclaimer-content::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

.disclaimer-content::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
}

.disclaimer-content::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .main-content {
    padding: 10px;
  }

  .disclaimer-overlay {
    padding: 0px;
  }

  .disclaimer-container {
    max-height: 95vh;
  }

  .disclaimer-content {
    padding: 20px;
  }

  .disclaimer-header h2 {
    font-size: 20px;
  }

  .disclaimer-text h3 {
    font-size: 16px;
  }

  .disclaimer-text h4 {
    font-size: 14px;
  }

  .detection-error-card {
    padding: 30px 20px;
    margin: 20px;
  }

  .action-buttons {
    flex-direction: column;
  }

  .retry-btn,
  .manual-btn {
    width: 100%;
  }

  .error-icon {
    width: 60px;
    height: 60px;
  }

  .error-icon i {
    font-size: 28px;
  }

  .error-title {
    font-size: 20px;
  }
}
</style>

<style>
/* 简洁模式样式 */
.simple-mode-container {
  padding: 5px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  background-color: #f5f7fa;
}

.simple-header {
  font-size: 18px;
  font-weight: bold;
  color: #333;
  margin-bottom: 20px;
}

.simple-stats {
  width: 50%;
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 1px 0;
}

.stat-item {
  width: 100%;
  display: flex;
  justify-content: space-between;
  font-size: 16px;
  padding: 10px 15px;
  background-color: white;
  border-radius: 6px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.stat-label {
  color: #666;
}

.stat-value {
  color: #333;
  font-weight: 600;
}

.simple-fire-icon {
  width: 16px;
  height: 16px;
  vertical-align: middle;
  margin-left: 3px;
}

.simple-actions {
  width: 100%;
  display: flex;
  gap: 15px;
  margin-top: 20px;
}

.simple-btn {
  width: 100%;
  flex: 1;
  height: 40px;
  font-size: 14px;
}

/* 全局样式 - 彻底解决滚动条和布局问题 */
.instructions-dialog .el-dialog {
  position: fixed !important;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2) !important;
  border-radius: 16px !important;
  overflow: hidden;
  max-height: 85vh;
  /* 限制最大高度 */
  display: flex;
  flex-direction: column;
}

.instructions-dialog .el-dialog__header {
  background: linear-gradient(135deg, #667eea, #764ba2);
  padding: 20px !important;
  margin: 0 !important;
  flex-shrink: 0;
}

.instructions-dialog .el-dialog__title {
  color: white !important;
  font-size: 18px !important;
  font-weight: 600 !important;
}

.instructions-dialog .el-dialog__headerbtn {
  top: 20px !important;
}

.instructions-dialog .el-dialog__headerbtn .el-dialog__close {
  color: white !important;
  font-size: 18px !important;
}

.instructions-dialog .el-dialog__body {
  padding: 20px 25px 0 25px !important;
  flex: 1;
  overflow: hidden !important;
  display: flex;
  flex-direction: column;
}

.instructions-dialog .el-dialog__footer {
  padding: 0 25px 20px 25px !important;
  flex-shrink: 0;
}

.instructions-dialog .el-dialog__wrapper {
  background-color: transparent !important;
}

.instructions-dialog .v-modal {
  display: none !important;
}

/* 防止任何滚动条闪烁 */
.instructions-dialog * {
  scrollbar-width: none !important;
  -ms-overflow-style: none !important;
}

.instructions-dialog *::-webkit-scrollbar {
  display: none !important;
  width: 0 !important;
  height: 0 !important;
}


/* 新增全屏遮罩层用于拦截点击 */
.alert-backdrop {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
  /* 确保在内容之上但在提示框之下 */
  background-color: rgba(0, 0, 0, 0.1);
  /* 轻微透明背景增强提示效果 */
  pointer-events: auto;
  /* 拦截点击事件 */
}

/* 调整提示框样式确保居中 */
.alert-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
  /* 确保在遮罩层之上 */
  pointer-events: none;
  /* 不拦截点击，让点击穿透到遮罩层 */
}

.alert-container {
  animation: popIn 0.3s ease-out, shake 0.5s ease-in-out 0.3s;
  pointer-events: auto;
  /* 提示框自身可以被点击（如果需要的话） */
}

.alert-content {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 24px;
  background-color: #fff;
  border: 1px solid #ffe082;
  border-radius: 12px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);
  max-width: 90%;
  width: auto;
}

/* 动画保持不变 */
@keyframes fadeInBg {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@keyframes popIn {
  from {
    opacity: 0;
    transform: scale(0.9);
  }

  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes shake {

  0%,
  100% {
    transform: translateX(0);
  }

  20% {
    transform: translateX(-5px);
  }

  40% {
    transform: translateX(5px);
  }

  60% {
    transform: translateX(-3px);
  }

  80% {
    transform: translateX(3px);
  }
}
</style>